home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
asm
/
alib11b.zip
/
CODE1.ZIP
/
DISKINFO
/
RAWREAD.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-10-04
|
10KB
|
403 lines
;
; This file contains a collection of runctions to read absolute (low level)
; disk addresses.
;---------------------------------------------------------------------------
; bump disk address
; inputs: cx,dx = disk address in int13 format
; current_param_ptr = ptr to parameters found by cmos check logic
; outputs: cx,dx = disk address +1 in int13 format
; carry set if at end of disk
;
bump_address:
push ax
push bx
push si
mov al,cl ;only -bx- can be modified
and al,3fh
;
; -al- = sector address
mov bx,cx ;get sector & cyl data
xchg bh,bl ;
rol bh,1
rol bh,1
and bh,3 ;remove sector bits
;
; -al- = sector address
; -bx- = track or cyl address
;
mov si,current_param_ptr ;point at param's from cmos check
inc al
cmp al,[si.sect_per_tk] ;check if at end of cyl
jbe bump_end2 ;jmp if not at end yet
call bump_head
mov al,1 ;start with sector 1
bump_end2:
;
; -al- = updated sector address
; -bx- = updated track address
; -dh- = updated head
;
mov cl,bh ;get track high bits
ror cl,1 ;move track
ror cl,1 ; high bits
or cl,al ;merge sector# in
mov ch,bl ;get track low bits
cmp bx,[si.last_cyl] ;check if at end of disk
jb bump_exit1
stc
jmp bump_exit2
bump_exit1:
clc
bump_exit2:
pop si
pop bx
pop ax
ret
;------------------------------------------------------------------------
; bump transfer address
;
bump_address:
mov al,CURRENT_SECTOR_ADR
inc al
cmp al,cs:[bp].SECTORS_PER_TRACK
jbe bump_end2
mov ah,CURRENT_DISK_HEAD
test ah,0c0h ;check for extended cyl. adr
jz bump_hd1 ;jmp if normal head
inc ah
mov CURRENT_SECTOR_ADR,1
;
; head has extended cyl. address in high bits, bump head
;
mov al,ah ;save head in -al-
and al,3fh ;isolate head
cmp al,cs:[bp].NUMBER_OF_HEADS
jne bump_ext1 ;jmp if no head overflow
;
; head has overflowed, set it back to zero.
;
and ah,0c0h
mov CURRENT_DISK_HEAD,ah
;
; bump cyl
;
mov ax,CURRENT_TRACK
inc ax ;bump track
test ax,0fc00h ;check if track overflow
jz bump_ext2 ;jmp if no track overflow
;
; track (cyl) has overflowed. bump bits in head
;
and ax,3ffh ;isolate new track bits
add CURRENT_DISK_HEAD,040H ;fix cyl. bits in head
jmp bump_ext2
;
; update head
;
bump_ext1:
mov CURRENT_DISK_HEAD,ah
ret
bump_ext2:
mov CURRENT_TRACK,ax
ret
;
; normal processing of head without extended cyl.
;
bump_hd1:
inc ah
cmp ah,cs:[bp].NUMBER_OF_HEADS
jne bump_end1
inc CURRENT_TRACK
test CURRENT_TRACK,0C00H ;check if track overflow
jz bump_end
;
; the cyl overflowed. set the high head bits
;
mov CURRENT_TRACK,0 ;set track to 0
mov ah,40h ;bump high head bit
jmp bump_end1
bump_end:
mov ah,0 ;start with side 0 again
bump_end1:
mov al,1 ;start with sector 1
mov CURRENT_DISK_HEAD,ah
bump_end2:
mov CURRENT_SECTOR_ADR,al
ret
;----------------------------------------------------------------------------
; subroutine to calculate an abolute disk address
; inputs: cx = disk cyl & sector in int13 format
; dh = disk head (high 2 bits can be used for cyl expansion)
;
; outputs: dx,ax = abs. adr
;
compute_dsk_abs_adr:
push si
push bx
;
; compute (sectors per cyl) * (number of heads) to be used later
;
push dx
mov si,current_param_ptr ;get disk parameters
sub bx,bx
mov bl,[si.sect_per_tk]
sub ax,ax
mov al,[si.heads]
mul bx ;compute heads * (sectors per cyl)
mov sect_per_cyl,ax
pop dx
dec cx ;make sectors zero based.
mov bl,dh ;save head
mov si,current_param_ptr ;point at disk parameters
mov ax,cx
xchg ah,al
rol ah,1
rol ah,1
and ax,3ffh ;isolate total cyl's
;
; check for extended cyl. bits in head
;
test bl,0c0h
jz cda1 ;jmp if normal cyl
add ax,1024
test bl,080h
jz cda1
add ax,1024
cda1:
mul sect_per_cyl ;total sectors in whole cyl's
;
; process head
;
push ax
push dx
mov al,bl
;
; DOS 3.3 fdisk has a bug, it sometimes sets the head to one more than it
; should. If head is out of bounds, then decrement.
; This problem only seems to occur on extended partitions.
;
and al,3fh ;remove cyl. extension bits
cmp al,[si.heads]
jb head_ok_now
dec al
head_ok_now:
mul [si.sect_per_tk]
mov bx,ax
pop dx
pop ax
add ax,bx ;add in heads * sect_per_tk
mov bx,0
adc dx,bx
mov bl,cl
and bx,03fh ;isolate whole sectors
add ax,bx
mov bx,0
adc dx,bx
pop bx
pop si
ret
;----------------------------------------------------------------------------
; compute int13 address from absolute disk address
; inputs: dx,ax = disk absolute address
; sect_per_cyl pre calculated.
; outputs: cx,dh = int13 address
;
compute_int13_adr:
push si
push bx
mov si,current_param_ptr ;point at disk parameters
div sect_per_cyl ;ax = cyl dx=remainder
mov cx,ax ;save cyl
mov ax,dx
div [si.sect_per_tk] ;al = heads ah=sector
mov dh,al ;save head
test ch,0c0h ;check for extended cyl
jz cia1 ;jmp if normal cyl
add dh,40h ;bump head if large cyl
test ch,80h
jz cia1 ;jmp if no extra bump
add dh,40h
and cx,3ffh ;isolate remaining cyl's
cia1:
xchg ch,cl
ror cl,1
ror cl,1
or cl,ah ;combine sector & cyl high
inc cl ;restore sector start of 1
pop bx
pop si
ret
;----------------------------------------------------------------------------
; form cyl. adr in -ax-
; inputs: -cx- has int13 cyl & sect
; -dh- has head
; output: -ax- has cyl
;
form_cyl:
push si
mov si,current_param_ptr ;point at disk parameters
mov ax,cx
xchg ah,al
rol ah,1
rol ah,1
and ax,3ffh ;isolate total cyl's
;
; check for extended cyl. bits in head
;
test dh,0c0h
jz fcc1 ;jmp if normal cyl
add ax,1024
test dh,080h
jz fcc1
add ax,1024
fcc1:
pop si
ret
;----------------------------------------------------------------------------
---------------------------------------------------------------------------
;
; compute int13 address from absolute disk address
; inputs: dx,ax = disk absolute address
; sect_per_cyl pre calculated. (.shc)
; outputs: cx,dh = int13 address
;
compute_int13_adr:
div pend_shc ;ax = cyl dx=remainder
mov cx,ax ;save cyl
mov ax,dx
div pend_sec_per_track ;al = heads ah=sector
mov dh,al ;save head
test ch,0c0h ;check for extended cyl
jz cia1 ;jmp if normal cyl
add dh,40h ;bump head if large cyl
test ch,80h
jz cia1 ;jmp if no extra bump
add dh,40h
and cx,3ffh ;isolate remaining cyl's
cia1:
xchg ch,cl
ror cl,1
ror cl,1
or cl,ah ;combine sector & cyl high
inc cl ;restore sector start of 1
ret
;---------------------------------------------------------------------------
write_sectors:
mov al,CURRENT_SECTOR_COUNT
mov ah,3 ;get disk request code
jmp short read_sectors2
;----------------------------------------------------------------------------
read_sectors:
mov al,CURRENT_SECTOR_COUNT
read_sectors1:
mov ah,2 ;get disk request code
read_sectors2:
les bx,CURRENT_USERS_BUFFER ;restore -ES:bx-
add byte ptr disk_transfers,al ;update stat's
adc byte ptr disk_transfers+1,0
jns read_sectors3 ;jmp if no overflow
shr disk_transfers,1 ;scale stat's
shr cache_hits,1
read_sectors3:
cmp translate_call,0
je read_sectors4 ;jmp if normal disk read
test current_disk_head,0c0h
jz read_sectors4 ;jmp if no possible translation
push ax
mov dl,current_drive
mov dh,0
mov ax,0ee00h
mov cx,1
pushf
call origional_int13 ;issue translation call
pop ax
mov dh,CURRENT_DISK_HEAD
and dh,3fh ;remove high head bits
jmp short read_sectors5
read_sectors4:
mov dh,current_disk_head
read_sectors5:
;
; join address into int13 format
; inputs CURRENT_TRACK,CURRENT_SECTOR
; output CX = int13 data
;
mov cl,byte ptr ds:CURRENT_TRACK+1 ;get track hi 2-bits
ror cl,1 ;move track
ror cl,1 ; high bits
or cl,CURRENT_SECTOR_ADR ;merge sector# in
mov ch,byte ptr ds:CURRENT_TRACK ;get track low bits
mov dl,CURRENT_DRIVE
pushf ;
call cs:origional_int13
cmp ah,0
jz rs_exit ;jmp if no disk errors
stc
rs_exit:
ret
;----------------------------------------------------------------------------
; subroutine to calculate sector number
; inputs: dh = int13 head
; ch = int13 cyl
; cl = int13 cyl hi + sector
; outupts: dx,ax = sector#
;
build_sector_number:
mov dl,cl ;get sector#
and dl,3fh ;isolate sector#
mov current_sector_adr,dl
dec dl ;zero base sector#
mov dl,dh ;get head#
mov current_disk_head,dl
and dl,3fh ;isolate head#
and dh,0c0h ;isolate cyl bits 11-10
and cl,0c0h ;isolate cyl bits 9-8
rol dh,1
rol dh,1 ;position bits 11-10
or cl,dh ;merge bits 11-10-9-8
rol cl,1
rol cl,1
xchg cl,ch
mov current_track,cx ;save cyl#
;
; compute big sector# (cyl*shc) + (head*sectors_per_track) + sector#
; Note: shc = (sectors_per_track * heads)
;
mov al,current_drv_data.sectors_per_track
mul dl ; (sectors_per_track * current_disk_head)
push ax ;save head# * sectors_per_track
mov ax,current_drv_data.shc ;get (total_heads * sect_per_track)
mul cx ; (cyl * shc)
pop cx
add ax,cx ;(cyl*sch) + (head * sectors_per_track)
adc dx,0
mov cl,current_sector_adr
dec cl ;make sectors zero based
add al,cl
adc ah,0
adc dx,0
ret